package com.ruowei.modules.sys.web;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ruowei.common.error.exception.BadRequestAlertException;
import com.ruowei.config.Constants;
import com.ruowei.modules.sys.domain.LoginRelatedLog;
import com.ruowei.modules.sys.domain.QLoginRelatedLog;
import com.ruowei.modules.sys.repository.LoginRelatedLogRepository;
import com.ruowei.modules.sys.web.dto.RegisterLogDTO;
import io.github.jhipster.web.util.HeaderUtil;
import io.github.jhipster.web.util.PaginationUtil;
import io.github.jhipster.web.util.ResponseUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.net.URISyntaxException;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Optional;

/**
 * REST controller for managing {@link LoginRelatedLog}.
 */
@RestController
@RequestMapping("/api")
@Api(tags = Constants.TAG_REGISTER)
@Transactional
public class LoginRelatedLogResource {

    private static final String ENTITY_NAME = "loginRelatedLog";
    private final Logger log = LoggerFactory.getLogger(LoginRelatedLogResource.class);
    private final LoginRelatedLogRepository loginRelatedLogRepository;
    private final QLoginRelatedLog qLoginRelatedLog = QLoginRelatedLog.loginRelatedLog;
    private final JPAQueryFactory queryFactory;
    @Value("${jhipster.clientApp.name}")
    private String applicationName;

    public LoginRelatedLogResource(LoginRelatedLogRepository loginRelatedLogRepository, JPAQueryFactory queryFactory) {
        this.loginRelatedLogRepository = loginRelatedLogRepository;
        this.queryFactory = queryFactory;
    }


    @PostMapping("/login-related-logs")
    public ResponseEntity<LoginRelatedLog> createLoginRelatedLog(@RequestBody LoginRelatedLog loginRelatedLog) throws URISyntaxException {
        log.debug("REST request to save LoginRelatedLog : {}", loginRelatedLog);
        if (loginRelatedLog.getId() != null) {
            throw new BadRequestAlertException("A new loginRelatedLog cannot already have an ID", ENTITY_NAME, "idexists");
        }
        LoginRelatedLog result = loginRelatedLogRepository.save(loginRelatedLog);
        return ResponseEntity.created(new URI("/api/login-related-logs/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, false, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

    @PostMapping("/login-related-logs/edit")
    public ResponseEntity<LoginRelatedLog> updateLoginRelatedLog(@RequestBody LoginRelatedLog loginRelatedLog) throws URISyntaxException {
        log.debug("REST request to update LoginRelatedLog : {}", loginRelatedLog);
        if (loginRelatedLog.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        LoginRelatedLog result = loginRelatedLogRepository.save(loginRelatedLog);
        return ResponseEntity.ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, false, ENTITY_NAME, loginRelatedLog.getId().toString()))
            .body(result);
    }

    @GetMapping("/login-related-logs")
    @ApiOperation(value = "条件搜索登录登出日志", notes = "作者： 曹状状")
    public ResponseEntity<List<RegisterLogDTO>> getAllQueriedLogs(@RequestParam(required = false) String vague,
                                                                  @RequestParam(required = false) ZonedDateTime startTime,
                                                                  @RequestParam(required = false) ZonedDateTime endTime,
                                                                  Pageable pageable) {
        BooleanBuilder booleanBuilder = new BooleanBuilder();
        if (startTime == null && endTime == null && vague == null) {

        } else {
            // 日志创建时间需晚于选定开始时间
            if (startTime != null) {
                booleanBuilder.and(qLoginRelatedLog.operateTime.after(startTime));
            }
            // 日志创建时间需先于选定结束时间
            if (endTime != null) {
                booleanBuilder.and(qLoginRelatedLog.operateTime.before(endTime));
            }
            // 模糊字段判断
            if (com.ruowei.common.lang.StringUtils.isNotEmpty(vague)) {
                Predicate predicateLoginCode = qLoginRelatedLog.loginCode.contains(vague);
                Predicate predicateUserName = qLoginRelatedLog.userName.contains(vague);
                booleanBuilder.andAnyOf(predicateLoginCode, predicateUserName);
            }
        }
        // 根据拦截条件选择对应数据
        JPAQuery<RegisterLogDTO> jpaQuery = queryFactory
            .select(Projections.bean(RegisterLogDTO.class, qLoginRelatedLog.id, qLoginRelatedLog.loginCode, qLoginRelatedLog.userName, qLoginRelatedLog.userRole, qLoginRelatedLog.operateType, qLoginRelatedLog.operateTime))
            .from(qLoginRelatedLog)
            .where(booleanBuilder)
            .orderBy(qLoginRelatedLog.operateTime.desc())
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize());
        Page<RegisterLogDTO> page = new PageImpl<>(jpaQuery.fetch(), pageable, jpaQuery.fetchCount());
        HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(page.getContent());
    }


    @GetMapping("/login-related-logs/{id}")
    public ResponseEntity<LoginRelatedLog> getLoginRelatedLog(@PathVariable Long id) {
        log.debug("REST request to get LoginRelatedLog : {}", id);
        Optional<LoginRelatedLog> loginRelatedLog = loginRelatedLogRepository.findById(id);
        return ResponseUtil.wrapOrNotFound(loginRelatedLog);
    }

    @PostMapping("/login-related-logs/{id}/delete")
    public ResponseEntity<Void> deleteLoginRelatedLog(@PathVariable Long id) {
        log.debug("REST request to delete LoginRelatedLog : {}", id);
        loginRelatedLogRepository.deleteById(id);
        return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, false, ENTITY_NAME, id.toString())).build();
    }
}
